﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Common;
using System.IO;
using System.Web.SessionState;

namespace UploadFile.ashx
{
    /// <summary>
    /// BlodUpload 的摘要说明
    /// </summary>
    public class BlodUpload : IHttpHandler, IRequiresSessionState
    {

        public void ProcessRequest(HttpContext context)
        {
            HttpFileCollection files = context.Request.Files;
            int totalPieces = 0;//总片段
            int index = 0;//当前片段
            int.TryParse(context.Request["totalPieces"], out totalPieces);
            int.TryParse(context.Request["index"], out index);
            //获取当前用户的SessionID
            string SessionID = Tools.ReturnSessionID();
            //服务器上保存的文件片段数
            string file_index = Tools.GetCacheValue(SessionID) == null ? "" : Tools.GetCacheValue(SessionID).ToString();
            int f_index = 0;
            int.TryParse(file_index, out f_index);
            //请求次数增加
            // f_index++;
            f_index++;
            if (Tools.GetCacheValue(SessionID) == null)
            {
                Tools.InsertCache(SessionID, f_index);//保存第几次请求文件
            }
            else
            {
                Tools.UpdateCache(SessionID, f_index);//保存第几次请求文件
            }
            //文件名字  
            string FileName = string.Empty;

            //定义一个临时文件夹，存放这些文件判断
            string TemporaryFiles = "/TemporaryFiles/";

            //文件上传的，目录
            string Uploads = "/Uploads/";

            //将每次文件保存到临时文件夹
            foreach (string str in files)
            {
                HttpPostedFile FileSave = files[str]; //用key获取单个文件对象HttpPostedFile
                FileName = files.Get(str).FileName;
                //判断文件夹是否存在，不存在就创建一个
                if (!Tools.PathExists(TemporaryFiles))
                {
                  bool status=Tools.CreatePath(TemporaryFiles);
                  if (!status)
                  {
                    context.Response.Write(Newtonsoft.Json.JsonConvert.SerializeObject(new Msg { status = false, msg = "临时文件夹创建失败" }));
                    context.Response.End();
                  }
                }
                string FilePath = TemporaryFiles + SessionID + "_" + index + FileName;//用户Id+上传时间+文件后缀
                FilePath = FilePath.Replace(" ", "");
                FilePath = FilePath.Replace("(", "");
                FilePath = FilePath.Replace(")", "");
                string AbsolutePath = context.Server.MapPath(FilePath);
                FileSave.SaveAs(AbsolutePath);    //将上传的文件段保存
            }
            if (f_index == totalPieces)//最后一次请求
            {
                //清空前面保存的文件请求次数
                Tools.DelCache(SessionID);
                //把所有文件合并到一起
                string filepath = MergeFiles(totalPieces, SessionID, FileName, TemporaryFiles, Uploads);
                context.Response.Write(Newtonsoft.Json.JsonConvert.SerializeObject(new Msg { status = true, msg = "文件合并完成", val = filepath }));
                context.Response.End();
            }
            else
            {
                context.Response.Write(Newtonsoft.Json.JsonConvert.SerializeObject(new Msg { status = true, msg = "文件段" + index + "接收成功" }));
                context.Response.End();
            }
        }

        /// <summary>
        /// 文件合并
        /// 参考地址 https://www.cnblogs.com/nidongde/p/6297609.html
        /// </summary>
        /// <param name="iSumFile">合并的文件个数</param>
        /// <param name="SessionID">当前用户的SessionID</param>
        /// <param name="FileName">文件的名称</param>
        /// <param name="TemporaryFiles">临时文件夹</param>
        /// <param name="Uploads">文件上传的文件夹</param>
        private string MergeFiles(int iSumFile, string SessionID, string FileName,string TemporaryFiles, string Uploads)
        {
            // string[] arrFileNames = Directory.GetFiles(strInputDirectory);
            //int iSumFile = arrFileNames.Length;
            //progressBar1.Maximum = iSumFile;
            //合并后的文件名称
            string NewFileName = DateTime.Now.ToString("yyyyMMddhhmmss");
            //判断文件夹是否存在，不存在就创建一个
            if (!Tools.PathExists(Uploads))
            {
                bool status = Tools.CreatePath(Uploads);
                //if (!status)
                //{
                //    context.Response.Write(Newtonsoft.Json.JsonConvert.SerializeObject(new Msg { status = false, msg = "临时文件夹创建失败" }));
                //    context.Response.End();
                //}
            }
            string NewFilePath = Uploads + NewFileName + FileName.Substring(FileName.LastIndexOf("."));//
            NewFilePath = NewFilePath.Replace(" ", "");
            NewFilePath = NewFilePath.Replace("(", "");
            NewFilePath = NewFilePath.Replace(")", "");
            string strMergeResultFile = System.Web.HttpContext.Current.Server.MapPath(NewFilePath);

            FileStream AddStream = new FileStream(strMergeResultFile, FileMode.OpenOrCreate);
            BinaryWriter AddWriter = new BinaryWriter(AddStream);

            long firstFileLength = 0;
            FileStream TempStream = null;
            BinaryReader TempReader = null;
            //文件长度列表
            string allFileLength = "";

            //文件长度和文件内容叠加
            {
                for (int i = 0; i < iSumFile; i++)
                {
                    //文件路径
                    string FilePath = TemporaryFiles + SessionID + "_" + i + FileName;//用户Id+上传时间+文件后缀
                    FilePath = FilePath.Replace(" ", "");
                    FilePath = FilePath.Replace("(", "");
                    FilePath = FilePath.Replace(")", "");
                    TempStream = new FileStream(System.Web.HttpContext.Current.Server.MapPath(FilePath), FileMode.Open);
                    TempReader = new BinaryReader(TempStream);
                    AddWriter.Write(TempReader.ReadBytes((int)TempStream.Length));
                    if (firstFileLength == 0)
                    {
                        firstFileLength = TempReader.BaseStream.Length;
                        allFileLength = firstFileLength.ToString().PadLeft(20, '0');
                    }
                    //暂时只处理2个文件的情况，下面是多文件
                    //allFileLength += "," + TempReader.BaseStream.Length.ToString().PadLeft(20, '0');

                    TempReader.Close();
                    TempStream.Close();
                    //删掉临时文件
                    File.Delete(System.Web.HttpContext.Current.Server.MapPath(FilePath));
                }
                allFileLength = allFileLength.Trim(',');

                //释放资源
                AddWriter.Flush();
                AddWriter.Close();
                AddStream.Close();
                TempStream = null;
                TempReader = null;
            }
            return NewFilePath;
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }


    class Msg
    {
        /// <summary>
        /// 返回当前请求的状态
        /// </summary>
        public bool status { get; set; }
        /// <summary>
        /// 返回请求的信息
        /// </summary>
        public string msg { get; set; }
        /// <summary>
        /// 需要返回到页面上的值
        /// </summary>
        public string val { get; set; }
        /// <summary>
        /// 返回请求后需要跳转的URL
        /// </summary>
        public string url { get; set; }
    }
}